package zaplog

import (
	"fmt"
	"path"
	"runtime"
	"strings"
	"time"

	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

var (
	Logger          *zap.Logger
	logInfoFileName = fmt.Sprintf("./logger/zap-info.log")
	logErrFileName  = fmt.Sprintf("./logger/zap-err.log")
)

func init() {
	encoderConfig := zap.NewDevelopmentEncoderConfig()
	// 设置日志时间格式
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	// 日志encoder 还是json encode，把日志进行格式化json格式的
	encoder := zapcore.NewJSONEncoder(encoderConfig)

	// topicErrors := zapcore.AddSync(ioutil.Discard)  //kafka topic
	fileInfoWriteSyncer := getFileLogWriter(logInfoFileName)
	fileErrWriteSyncer := getFileLogWriter(logErrFileName)
	core := zapcore.NewTee(
		// zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapcore.DebugLevel),  // 打印到控制台
		// zapcore.NewCore(zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), topicErrors, zapcore.ErrorLevel),   // 打印到kafka 待验证
		zapcore.NewCore(encoder, fileInfoWriteSyncer, zapcore.InfoLevel), // 打印到指定的日志文件
		zapcore.NewCore(encoder, fileErrWriteSyncer, zapcore.ErrorLevel), // 打印到指定的日志文件
	)
	Logger = zap.New(core)
}

func getFileLogWriter(logFileName string) zapcore.WriteSyncer {
	lumberRotateLogs, err := rotatelogs.New(
		strings.Replace(logFileName, ".log", "", -1)+"-%Y%m%d.log",
		rotatelogs.WithLinkName(logFileName),
		/*	rotatelogs.WithRotationCount(2),        // 2天的日志
			rotatelogs.WithRotationSize(210000000), // 一个文件200MB*/
		rotatelogs.WithMaxAge(7*24*time.Hour),
		rotatelogs.WithRotationTime(24*time.Hour),
	)
	if err != nil {
		panic(err)
	}
	return zapcore.AddSync(lumberRotateLogs)
}

func getCallerInfoForLog() (callerFields []zap.Field) {
	pc, file, line, ok := runtime.Caller(2)
	if !ok {
		return
	}
	funcName := runtime.FuncForPC(pc).Name()
	funcName = path.Base(funcName)

	callerFields = append(callerFields, zap.String("func", funcName), zap.String("file", file), zap.Int("line", line))
	return
}

func Info(message string, fields ...zap.Field) {
	callerFields := getCallerInfoForLog()
	fields = append(fields, callerFields...)
	Logger.Info(message, fields...)
}

func Debug(message string, fields ...zap.Field) {
	callerFields := getCallerInfoForLog()
	fields = append(fields, callerFields...)
	Logger.Debug(message, fields...)
}

func Error(message string, fields ...zap.Field) {
	callerFields := getCallerInfoForLog()
	fields = append(fields, callerFields...)
	Logger.Error(message, fields...)
}
